package com.ugoodtech.mdcc.web.controller;

import com.mysema.query.BooleanBuilder;
import com.ugoodtech.mdcc.core.Constants;
import com.ugoodtech.mdcc.core.LogConstants;
import com.ugoodtech.mdcc.core.domain.*;
import com.ugoodtech.mdcc.core.domain.VstarCustomerSatisfactionReport.CustomerStatVo;
import com.ugoodtech.mdcc.core.domain.VstarCustomerSatisfactionReport.VstarCustomerSatisfactionReport;
import com.ugoodtech.mdcc.core.exception.UsernameAlreadyExistException;
import com.ugoodtech.mdcc.core.repository.*;
import com.ugoodtech.mdcc.web.dto.JsonResponse;
import com.ugoodtech.mdcc.web.dto.ServerResponse;
import com.ugoodtech.mdcc.web.service.UserService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Copyright © 2013 All Rights Reserved, Ugood Technology, Inc.
 */
@RestController
@RequestMapping("/user")
public class UserController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    @Autowired
    UserRepository userRepository;
    @Autowired
    UserService userService;

    @Autowired
    FeedbackRepository feedbackRepository;


    @Autowired
    private PasswordEncoder passwordEncoder;

    @RequestMapping(value = "/getUsers", method = RequestMethod.GET)
    public JsonResponse getUsers(
            @RequestParam(value = "searchParam") String searchParam, Pageable pageable) throws Exception {
        isUserLogin();
        Page<User> users = userService.queryUser(searchParam, Constants.ROLE_ADMIN, pageable);
        return JsonResponse.successResponseWithPageData(users);
    }


    @ApiOperation("添加用户")
    @RequestMapping(value = "/addUser", method = RequestMethod.POST)
    public JsonResponse addUser(
            @ApiParam(value = "用户账号", required = true) @RequestParam(required = true) String username,
            @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String realName,
            @ApiParam(value = "手机号码", required = false) @RequestParam(required = false) String telephone,
            @ApiParam(value = "角色id", required = true) @RequestParam(required = true) Long userRoleId) throws Exception {
        isUserLogin();
        try {
            User user = new User();
            user.setUsername(username);
//            user.setRealName(realName);
//            user.setTelephone(telephone);
            user.setPassword(Constants.INIT_PASSWORD);
//            Set<UserRole> roles=user.getRoles();
//            if(null==roles||roles.size()==0){
//                roles=new HashSet<>();
//            }
//            roles.add(userRoleRepository.findOne(userRoleId));
//            user.setRoles(roles);

            userService.createUser(user, userRoleId);
        } catch (UsernameAlreadyExistException e) {
            return JsonResponse.errorResponseWithError("UsernameAlreadyExistException", "用户名已存在");
        }
        userLogService.addUserLog(this.getCurrentUser(), null,
                LogConstants.operate_type_add,
                LogConstants.business_type_people, null, null);
        return JsonResponse.successResponse();
    }

    @RequestMapping(value = "/getLoginUser", method = RequestMethod.GET)
    public JsonResponse getLoginUser() throws Exception {
        return JsonResponse.successResponseWithData(this.getCurrentUser());
    }

    @RequestMapping(value = "/getUser", method = RequestMethod.GET)
    public JsonResponse getUser(@RequestParam Long userId) throws Exception {
        isUserLogin();
        User user = userRepository.findOne(userId);
        return JsonResponse.successResponseWithData(user);

    }

    @RequestMapping(value = "/initUserPassword", method = RequestMethod.POST)
    public JsonResponse editUser(@RequestParam Long userId) throws Exception {
        isUserLogin();
        User user = userRepository.findOne(userId);
        userService.initPassword(user);
        return JsonResponse.successResponse();
    }

    @ApiOperation("修改用户")
    @RequestMapping(value = "/editUser", method = RequestMethod.POST)
    public JsonResponse editUser(@ApiParam(value = "用户数据库id", required = true) @RequestParam Long userId,
                                 @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String realName,
                                 @ApiParam(value = "手机号码", required = false) @RequestParam(required = false) String telephone,
                                 @ApiParam(value = "角色id", required = true) @RequestParam(required = true) Long userRoleId)

            throws Exception {
        isUserLogin();
        User user = userRepository.findOne(userId);
//        user.setRealName(realName);
        user.setUsername(realName);
//        user.setTelephone(telephone);
//        Set<UserRole> roles=user.getRoles();
//        if(null==roles||roles.size()==0){
//            roles=new HashSet<>();
//        }
//        roles.add(userRoleRepository.findOne(userRoleId));
//        user.setRoles(roles);

//        user.setPassword(null);
        userRepository.save(user);
        userLogService.addUserLog(this.getCurrentUser(), null,
                LogConstants.operate_type_edit,
                LogConstants.business_type_people, null, null);
        return JsonResponse.successResponse();
    }

    @ApiOperation("删除单条用户")
    @RequestMapping(value = "/deleteUser", method = RequestMethod.POST)
    public JsonResponse deleteUsers(
            @ApiParam(value = "用户数据库id", required = true) @RequestParam Long userId) throws Exception {
        isUserLogin();

        User user = userRepository.findOne(userId);
        userService.delete(userId);
        user.setUsername(user.getUsername() + "_" + System.currentTimeMillis());
        user.setDeleted(true);
        user.setEnabled(false);
        userRepository.save(user);
        userLogService.addUserLog(this.getCurrentUser(), null,
                LogConstants.operate_type_delete,
                LogConstants.business_type_people, null, null);
        return JsonResponse.successResponse();

    }

    @ApiOperation("删除多条用户")
    @RequestMapping(value = "/deleteUsers", method = RequestMethod.POST)
    public JsonResponse deleteUsers(
            @ApiParam(value = "用户数据库id组成的数组", required = true) @RequestParam Long[] userIds) throws Exception {
        isUserLogin();
        if (null != userIds && userIds.length > 0) {
            userService.delete(Arrays.asList(userIds));
            for (Long id : userIds) {
                User user = userRepository.findOne(id);
                user.setUsername(user.getUsername() + "_" + System.currentTimeMillis());
                user.setDeleted(true);
                user.setEnabled(false);
                userRepository.save(user);
            }
            userLogService.addUserLog(this.getCurrentUser(), null,
                    LogConstants.operate_type_delete,
                    LogConstants.business_type_people, null, null);
            return JsonResponse.successResponse();
        } else {
            return JsonResponse.errorResponseWithError("fail", "error user id");
        }

    }

    @ApiOperation("修改用户密码")
    @RequestMapping(value = "/changeUserPwd", method = RequestMethod.POST)
    public JsonResponse changeUserPwd(Long loginUserId,
                                      @ApiParam(value = "旧密码", required = true) @RequestParam(value = "oldPwd") String oldPwd,
                                      @ApiParam(value = "新密码", required = true) @RequestParam(value = "newPwd") String newPwd) throws Exception {
        User currentUser = userRepository.findOne(loginUserId);
        if (null == currentUser) {
            return JsonResponse.errorResponseWithError("", "抱歉，请重新登录");
        } else {
            logger.debug("当前登录用户id:" + currentUser.getId());
        }
        if (oldPwd.equals(newPwd)) {
            return JsonResponse.errorResponseWithError("", "抱歉，新密码不能与旧密码一样");
        }
        try {
            boolean result = userService.changePassword(currentUser, newPwd, oldPwd);
            if (result) {
                return JsonResponse.successResponseWithData("修改成功");
            } else {
                return JsonResponse.errorResponseWithError("", "抱歉，修改失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.debug("failed,Original password error");
            return JsonResponse.errorResponseWithError("", "抱歉，修改失败");

        }
    }

    @RequestMapping(value = "/getFeedbacks", method = RequestMethod.GET)
    public JsonResponse getFeedbacks(
            Pageable pageable) throws Exception {
        Pageable pageable1 = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), new Sort(Sort.Direction.DESC, "creationTime"));
        Page<Feedback> feedbacks = feedbackRepository.findAll(pageable1);
        return JsonResponse.successResponseWithPageData(feedbacks);
    }

    @ApiOperation("重置用户密码")
    @RequestMapping(value = "/restPassword", method = RequestMethod.POST)
    public JsonResponse restPassword(@ApiParam(value = "用户数据库id", required = true) @RequestParam(value = "userId") Long userId) {
        isUserLogin();
        User user = userRepository.findOne(userId);
        if (user == null) {
            return JsonResponse.errorResponseWithError("500", "未找到此系统用户");
        }
        user.setPassword(passwordEncoder.encode(Constants.INIT_PASSWORD));
        userRepository.save(user);
        return JsonResponse.successResponse();
    }

    @ApiOperation("激活/禁用系统用户")
    @RequestMapping(value = "/enableUser", method = RequestMethod.POST)
    public JsonResponse enableUser(@ApiParam(value = "用户数据库id", required = true) @RequestParam(value = "userId") Long userId,
                                   @ApiParam(value = "激活/禁用", required = true) @RequestParam(value = "enabled") boolean enabled) {
        isUserLogin();
        User user = userRepository.findOne(userId);
        if (user == null) {
            return JsonResponse.errorResponseWithError("500", "未找到此系统用户");
        }
        if (user.isEnabled() == false && enabled == false) {
            return JsonResponse.errorResponseWithError("500", "该用户已被禁用");
        }
        if (user.isEnabled() == true && enabled == true) {
            return JsonResponse.errorResponseWithError("500", "该用户已被激活");
        }
        user.setEnabled(enabled);
        userRepository.save(user);
        return JsonResponse.successResponse();
    }


    @Autowired
    private StationReportRepository stationReportRepository;

    @Autowired
    private UserProfileRepository userProfileRepository;

    @Autowired
    private CustomerRegularReportRepository customerRegularReportRepository;

    /**
     * 获取填写过报告的技术人员
     *
     * @return
     */
    private List<String[]> getReportUser(Long start, Long end) {
//        Long[] userIdArray = {437L, 455L, 483L, 484L, 485L, 486L, 487L, 488L, 489L, 490L, 587L, 589L, 591L, 592L, 613L, 614L, 615L, 656L};

        List<String[]> userNameList = new ArrayList<>();
        QStationReport qStationReport = QStationReport.stationReport;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qStationReport.deleted.eq(false));
        builder.and(qStationReport.enabled.eq(true));
        builder.and(qStationReport.category.eq(Constants.TECHCOLOR_REPORT));
        builder.and(qStationReport.creationTime.after(new Date(start)));
        builder.and(qStationReport.creationTime.before(new Date(end)));
//        builder.and(qStationReport.user.id.in(userIdArray));
        List<StationReport> stationReportList = (List<StationReport>) stationReportRepository.findAll(builder);
        String[] userStr = new String[1];
        userStr[0] = String.valueOf(stationReportList.size());
        userNameList.add(userStr);

//        qStationReport = QStationReport.stationReport;
//        builder = new BooleanBuilder();
//        builder.and(qStationReport.deleted.eq(false));
//        builder.and(qStationReport.enabled.eq(true));
//        builder.and(qStationReport.category.eq(Constants.SERVICE_REPORT));
//        builder.and(qStationReport.creationTime.after(new Date(start)));
//        builder.and(qStationReport.creationTime.before(new Date(end)));
//        builder.and(qStationReport.user.id.in(userIdArray));
//        stationReportList = (List<StationReport>) stationReportRepository.findAll(builder);
//        userStr = new String[1];
//        userStr[0] = String.valueOf(stationReportList.size());
//        userNameList.add(userStr);
//
//
//        Integer score = 0;
//        Integer customerReportNum = 0;
//        for (StationReport regularReport : stationReportList) {
//            QCustomerRegularReport qCustomerRegularReport = QCustomerRegularReport.customerRegularReport;
//            BooleanBuilder builder1 = new BooleanBuilder();
//            builder1.and(qCustomerRegularReport.deleted.eq(false));
//            builder1.and(qCustomerRegularReport.enabled.eq(true));
//            builder1.and(qCustomerRegularReport.regularReport.id.eq(regularReport.getId()));
//            CustomerRegularReport customerRegularReport = customerRegularReportRepository.findOne(builder1);
//            if (null != customerRegularReport && StringUtils.isNotEmpty(customerRegularReport.getScore())) {
//                score += Integer.valueOf(customerRegularReport.getScore());
//                customerReportNum += 1;
//            }
//        }
//        userStr = new String[1];
//        userStr[0] = customerReportNum.toString();
//        userNameList.add(userStr);
//
//        userStr = new String[1];
//        if (score != 0) {
//            userStr[0] = String.valueOf(score / stationReportList.size());
//        }
//        userStr[0] = "0";
//        userNameList.add(userStr);

//        Map<Long, Long> userIdMap = new HashMap<>();
//        for (StationReport report : stationReportList) {
//            if (userIdMap.containsKey(report.getUser().getId())) {
//                Long value = userIdMap.get(report.getUser().getId());
//                userIdMap.put(report.getUser().getId(), value + 1);
//            } else {
//                userIdMap.put(report.getUser().getId(), 1L);
//            }
//        }

//        for (Map.Entry<Long, Long> entry : userIdMap.entrySet()) {
//            UserProfile userProfile = userProfileRepository.findByUserId(entry.getKey());
//            if (null != userProfile && StringUtils.isNotEmpty(userProfile.getRealName())) {
//                String[] userStr = new String[2];
//                userStr[0] = userProfile.getRealName();
//                userStr[1] = entry.getValue().toString();
//                userNameList.add(userStr);
//            }
//        }

        return userNameList;
    }

    @Autowired
    private StationRegularServiceReportRepository stationRegularServiceReportRepository;

    @Autowired
    private QuestionAnswerOptionRepository questionAnswerOptionRepository;

    private List<String[]> getServiceReport() {
        QStationReport qStationReport = QStationReport.stationReport;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qStationReport.deleted.eq(false));
        builder.and(qStationReport.enabled.eq(true));
        builder.and(qStationReport.category.eq(Constants.SERVICE_REPORT));
        builder.and(qStationReport.reportType.eq(Constants.REPORT_TYPE_COMPLETE));
        List<StationReport> stationReportList = (List<StationReport>) stationReportRepository.findAll(builder);
        Map<String, Integer> map = new HashMap<>();
        for (StationReport report : stationReportList) {
            StationRegularServiceReport stationRegularServiceReport = stationRegularServiceReportRepository.selectQuestionOther(report.getId(), 155L);
            String answerIds = stationRegularServiceReport.getAnswerId();
            if (StringUtils.isEmpty(answerIds)) {
                continue;
            }
            for (String answerId : answerIds.split(",")) {
                if (map.containsKey(answerId)) {
                    Integer value = map.get(answerId);
                    map.put(answerId, value + 1);
                } else {
                    map.put(answerId, 1);
                }
            }
            if (StringUtils.isNotEmpty(stationRegularServiceReport.getAnswerOther())) {
                if (map.containsKey(stationRegularServiceReport.getAnswerOther())) {
                    Integer value = map.get(stationRegularServiceReport.getAnswerOther());
                    map.put(stationRegularServiceReport.getAnswerOther(), value + 1);
                } else {
                    map.put(stationRegularServiceReport.getAnswerOther(), 1);
                }
            }
        }
        List<String[]> strList = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            String[] str = new String[3];
            try {
                QuestionAnswerOption questionAnswerOption = questionAnswerOptionRepository.findOne(Long.valueOf(entry.getKey()));
                if (null == questionAnswerOption || StringUtils.isEmpty(questionAnswerOption.getName())) {
                    continue;
                }
                str[0] = questionAnswerOption.getName();
            } catch (Exception e) {
                str[0] = entry.getKey();
            }
            str[1] = entry.getValue().toString();
            str[2] = getServiceReportDayNum(entry.getKey());
            strList.add(str);
        }
        return strList;
    }

    private String getServiceReportDayNum(String answerId) {
        QStationRegularServiceReport qStationRegularServiceReport = QStationRegularServiceReport.stationRegularServiceReport;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qStationRegularServiceReport.deleted.eq(false));
        builder.and(qStationRegularServiceReport.enabled.eq(true));
        if (answerId.equals("183") || answerId.equals("184") || answerId.equals("185") || answerId.equals("186") || answerId.equals("187") || answerId.equals("188") ||
                answerId.equals("189") || answerId.equals("190") || answerId.equals("191")) {
            builder.and(qStationRegularServiceReport.answerId.like(answerId));
        } else {
            builder.and(qStationRegularServiceReport.answerOther.like(answerId));
        }
        List<StationRegularServiceReport> stationRegularServiceReportList = (List<StationRegularServiceReport>) stationRegularServiceReportRepository.findAll(builder);
        Integer dayNum = 0;
        for (StationRegularServiceReport report : stationRegularServiceReportList) {
            dayNum += getDayNum(report.getStationReport().getEndServiceTime(), report.getStationReport().getStartServiceTime());
        }
        return dayNum.toString();
    }


    private Integer getDayNum(Date endDate, Date startDate) {
        try {
            //将转换的两个时间对象转换成Calendard对象
            Calendar can1 = Calendar.getInstance();
            can1.setTime(endDate);
            Calendar can2 = Calendar.getInstance();
            can2.setTime(startDate);
            //拿出两个年份
            int year1 = can1.get(Calendar.YEAR);
            int year2 = can2.get(Calendar.YEAR);
            //天数
            int days = 0;
            Calendar can = null;
            //如果can1 < can2
            //减去小的时间在这一年已经过了的天数
            //加上大的时间已过的天数
            if (can1.before(can2)) {
                days -= can1.get(Calendar.DAY_OF_YEAR);
                days += can2.get(Calendar.DAY_OF_YEAR);
                can = can1;
            } else {
                days -= can2.get(Calendar.DAY_OF_YEAR);
                days += can1.get(Calendar.DAY_OF_YEAR);
                can = can2;
            }
            for (int i = 0; i < Math.abs(year2 - year1); i++) {
                //获取小的时间当前年的总天数
                days += can.getActualMaximum(Calendar.DAY_OF_YEAR);
                //再计算下一年。
                can.add(Calendar.YEAR, 1);
            }
            if (days <= 0) {
                return 1;
            }
            return days;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 1;
    }


    @RequestMapping(value = "/getReportServiceNumExport", method = RequestMethod.GET)
    public JsonResponse getReportServiceNumExport(HttpServletRequest request) {
        String templetPath = request.getSession().getServletContext().getRealPath("");
        String fileName = "常规服务报告服务次数.xlsx";
        List<String[]> reportNum = getServiceReport();
        XSSFWorkbook wb = getServiceNumExcel(reportNum);
        try {
            FileOutputStream outputStream = new FileOutputStream(new File(templetPath + "/export/" + fileName));
            wb.write(outputStream);
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JsonResponse.successResponseWithData("http://vr.duluxdesigner.com.cn/export/" + fileName);
    }

    public XSSFWorkbook getServiceNumExcel(List<String[]> reportNum) {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFRow row1;
        XSSFSheet sheet = workbook.createSheet("次数");
        XSSFCell cell2;
        for (int i = 0; i < reportNum.size(); i++) {
            row1 = sheet.createRow(i + 1);
            for (int j = 0; j < reportNum.get(i).length; j++) {
                cell2 = row1.createCell(j);
                cell2.setCellValue(reportNum.get(i)[j]);
            }
        }
        return workbook;
    }


    @RequestMapping(value = "/getServiceReportExcel", method = RequestMethod.GET)
    public JsonResponse getReportUserExport(HttpServletRequest request, Long start, Long end) throws Exception {
        String templetPath = request.getSession().getServletContext().getRealPath("");
        String fileName = "填写报告人员.xlsx";
        //sheet名
        String sheetName = "人员姓名";
        List<String[]> userNameList = getReportUser(start, end);
        XSSFWorkbook wb = getServiceReportExcel(sheetName, null, userNameList);
        //响应到客户端
        try {
            FileOutputStream outputStream = new FileOutputStream(new File(templetPath + "/export/" + fileName));
            wb.write(outputStream);
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JsonResponse.successResponseWithData("http://vr.duluxdesigner.com.cn/export/" + fileName);
    }

    public XSSFWorkbook getServiceReportExcel(String sheetName, XSSFWorkbook workbook, List<String[]> userNameList) throws Exception {
        // 第一步，创建一个HSSFWorkbook，对应一个Excel文件
        if (workbook == null) {
            workbook = new XSSFWorkbook();
        }

        // 第二步，在workbook中添加一个sheet,对应Excel文件中的sheet
        XSSFSheet sheet = workbook.createSheet(sheetName);

        // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
        XSSFRow row1;

        //创建内容
        XSSFCell cell2;
        for (int i = 0; i < userNameList.size(); i++) {
            row1 = sheet.createRow(i + 1);
            for (int j = 0; j < userNameList.get(i).length; j++) {
                cell2 = row1.createCell(j);
                cell2.setCellValue(userNameList.get(i)[j]);
            }

        }
        return workbook;
    }
    /**
     * 根据输入的用户姓名关键字获取用户姓名列表 该接口用于业绩报告-数据统计模块
     */
    @RequestMapping(value = "/getNameListByKey", method = RequestMethod.GET)
    @ResponseBody
    public ServerResponse getNameListByKey(
            @RequestParam(value = "name", required = false, defaultValue = "") String name) {
        List<String> nameListByKey = userService.getUserNameListOfEmployee(name);
        return ServerResponse.success(ServerResponse.MSG_SUCCESS, nameListByKey);
    }

}
